package com.ybw.aop;

import com.ybw.constant.MDCConstant;
import com.ybw.util.MyStringUtils;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

/**
 * 定时任务监控
 *
 * @author weixiansheng
 * @version V1.0
 * @className TaskMonitorAspect
 * @date 2023/11/20
 **/
@Aspect
@Component
@Slf4j
public class TaskMonitorAspect {

    ThreadLocal<LogRecord> logRecordThreadLocal = new ThreadLocal<>();

    /**
     * 拦截定时任务注解
     *
     * @methodName: scheduledTask
     * @return: void
     * @author: weixiansheng
     * @date: 2023/11/20
     **/
    @Pointcut("@annotation(org.springframework.scheduling.annotation.Scheduled)")
    public void scheduledTask() {
        // 定义拦截的方法，这里拦截所有包名为com.example.yourpackage的方法
    }

    @Before("scheduledTask()")
    public void beforeThreadStart(JoinPoint joinPoint) {
        //1、日志跟踪
        MDC.put(MDCConstant.REQUEST_ID, MyStringUtils.generateUUIDNoCenterLine());
        //2、记录当前线程的执行方法名和方法所在类的全限定名
        String name = joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName();
        logRecordThreadLocal.set(new LogRecord(System.currentTimeMillis(), name));
        log.info("定时任务:{}开始", name);
    }

    @After("scheduledTask()")
    public void afterThreadEnd(JoinPoint joinPoint) {
        //1、获取日志记录
        LogRecord logRecord = logRecordThreadLocal.get();
        log.info("定时任务所花费时间{}毫秒,定时任务:{}", System.currentTimeMillis() - logRecord.getStartTime(), logRecord.getName());
        //2、删除当前线程MDC中指定的键值对
        MDC.remove(MDCConstant.REQUEST_ID);
    }

    @AllArgsConstructor
    @Getter
    class LogRecord {
        /**
         * 开始时间
         *
         * @author: ybwei
         * @date: 2022/3/22 9:53
         */
        private Long startTime;
        /**
         * 接口地址
         *
         * @author: ybwei
         * @date: 2022/3/22 9:55
         */
        private String name;
    }
}
